#  This file is part of OpenLightingDesigner.
# 
#  OpenLightingDesigner is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  OpenLightingDesigner is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with OpenLightingDesigner.  If not, see <http://www.gnu.org/licenses/>.
#
# Parameter.py
# Copyright (c) 2010 - 2011 Matthew Reid

from Bases import setID
from Bases import OSCBaseObject

class ParameterBase(OSCBaseObject):
    _saved_class_name = 'ParameterBase'
    #_saved_attributes = ['name', 'id', 'parent_attribute_id', 'val_min', 'val_max']
    _saved_attributes = ['parent_attribute_id']
    def __init__(self, **kwargs):
        self.parent_attribute = kwargs.get('parent_attribute')
        super(ParameterBase, self).__init__(**kwargs)
        if 'deserialize' not in kwargs:
            self.id = setID(kwargs.get('id', None))
            self.parent_attribute_id = getattr(self.parent_attribute, 'id', None)
        #if getattr(self, 'id', None) is None:
        #    self.id = setID(kwargs.get('id', None))
    

class GlobalParameter(ParameterBase):
    _saved_class_name = 'GlobalParameter'
    _saved_attributes = ['name', 'id']
    def __init__(self, **kwargs):
        super(GlobalParameter, self).__init__(**kwargs)
        if 'deserialize' not in kwargs:
            self.name = kwargs.get('name', '')
            
class DefinitionParameter(ParameterBase):
    _saved_class_name = 'DefinitionParameter'
    _saved_attributes = ['id', 'value_min', 'value_max', 'GlobalParameter_id']
    def __init__(self, **kwargs):
        #if not hasattr(self, 'GlobalParameter'):
        #    self.GlobalParameter = kwargs.get('GlobalParameter')
        super(DefinitionParameter, self).__init__(**kwargs)
        if self.saved_class_name == DefinitionParameter._saved_class_name:
            d = kwargs.get('deserialize')
            if d is not None:
                gparam_id = d['attrs']['GlobalParameter_id']
                gparam = self.parent_attribute.GlobalAttribute.indexed_parameters[gparam_id]
            else:
                gparam = kwargs.get('GlobalParameter')
                self.GlobalParameter_id = gparam.id
                self.value_min = kwargs.get('value_min', 0)
                self.value_max = kwargs.get('value_max', 0)
            self.GlobalParameter = gparam
        
    @property
    def name(self):
        return self.GlobalParameter.name
    #@property
    #def id(self):
    #    return self.GlobalParameter.id
    @property
    def range_str(self):
        return str(self.value_min) + ' - ' + str(self.value_max)
        
class PatchedParameter(DefinitionParameter):
    _saved_class_name = 'PatchedParameter'
    _saved_attributes = ['DefinitionParameter_id']
    _Properties = {'value':dict(type=int)}
    def __init__(self, **kwargs):
        #self.DefinitionParameter = kwargs.get('DefinitionParameter')
        #self.GlobalParameter = self.DefinitionParameter.GlobalParameter
        self._active = False
        super(PatchedParameter, self).__init__(**kwargs)
        self.register_signal('active_changed', 'value_changed')
        d = kwargs.get('deserialize')
        if d is not None:
            dparam_id = d['attrs']['DefinitionParameter_id']
            dparam = self.parent_attribute.DefinitionAttribute.indexed_parameters[dparam_id]
        else:
            dparam = kwargs.get('DefinitionParameter')
            self.DefinitionParameter_id = dparam.id
        self.DefinitionParameter = dparam
        self.Properties['value'].min = dparam.value_min
        self.Properties['value'].max = dparam.value_max
        self.GlobalParameter = dparam.GlobalParameter
        self.value = self.index
        self.bind(value=self.on_value_set)
        
    @property
    def value_min(self):
        return self.DefinitionParameter.value_min
    @value_min.setter
    def value_min(self, value):
        pass
        
    @property
    def value_max(self):
        return self.DefinitionParameter.value_max
    @value_max.setter
    def value_max(self, value):
        pass
        
    @property
    def active(self):
        value = self.parent_attribute.value
        return value >= self.value_min and value <= self.value_max
    @active.setter
    def active(self, value):
        if value:
            self.parent_attribute.value = self.value_min
        else:
            self.parent_attribute.value = 0
        
    @property
    def index(self):
        if not self.active:
            return None
        value = self.parent_attribute.value
        return value - self.value_min
    @index.setter
    def index(self, value):
        if value is None:
            return
        if value <= self.value_max - self.value_min:
            self.parent_attribute.value = value + self.value_min
            
    def on_value_set(self, **kwargs):
        value = kwargs.get('value')
        self.index = value
        print self.name, value
        self.emit('value_changed', attribute=self.parent_attribute, parameter=self, value=value)
        
#    @property
#    def value(self):
#        return self.index
#    @value.setter
#    def value(self, value):
#        self.index = value
    
    def check_active(self, value):
        if value >= self.value_min and value <= self.value_max:
            return True
        
    def calculate_value(self, index):
        if index is None:
            index = 0
        if index > self.value_max - self.value_min:
            return False
        return index + self.value_min
